package woordvoorspeller.gui;

import woordvoorspeller.core.WordList;
import woordvoorspeller.core.WordListEntry;
import woordvoorspeller.core.WordListFormatException;

import javax.swing.*;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * The WordsListWidget provides the GUI implementation of the WordsList. 
 * @author Brian Setz
 * @version 0.1
 */
public class WordListWidget extends JPanel
{
	private static final long serialVersionUID = 1L;
	
	private JList list;
	private JTextField sentenceField;
	private DefaultListModel listModel;
	private WordList wordList;
	private ArrayList<WordListEntry> currentWordList;
	
	/**
	 * Creates a default WordsListWidget
	 */
	public WordListWidget()
	{
		// Create the word lists.
		try
		{
			wordList = new WordList("basis.txt");
		}
		catch(WordListFormatException e)
		{
			System.out.println(e.getMessage());
			e.printStackTrace();
		}
		currentWordList = new ArrayList<WordListEntry>();
		
		//TODO: Good layout - I suck at this.
		BoxLayout layout = new BoxLayout(this, BoxLayout.Y_AXIS);
		this.setLayout(layout);
		
		// Create the list model, list, and set the selection mode to single.
		listModel = new DefaultListModel();
		list = new JList(listModel);
		list.addMouseListener(new WordListMouseAdapter(this, list));
		list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);		
		
		// Scrolling list.
		JScrollPane listScroller = new JScrollPane(list);
		this.add(listScroller);
		
		// Create a text field for entering sentences, add a KeyListener and add it to the JPanel.
		sentenceField = new JTextField();
		sentenceField.addKeyListener(new WordListKeyListener(this)); 
		this.add(sentenceField);
	}

	/**
	 * Retrieves the selected word from the list. Only one selection is possible.
	 * @return The selected word.
	 */
	public String getSelectedWord()
	{
		return (String)list.getSelectedValue();
	}
	
	/**
	 * Retrieves a word from the current list using the given index.
	 * @param index The index.
	 * @return The word at the given index.
	 */
	public String getWord(int index)
	{
		// Check if the currentWordList is not empty if the given index exists.
		if(!currentWordList.isEmpty() && currentWordList.size() > index)
			return currentWordList.get(index).getWord();
		return "";
	}
	
	/**
	 * Retrieves the entire WordList.
	 * @return The WordList.
	 */
	public WordList getWordList()
	{
		return wordList;
	}
	
	/**
	 * Retrieves the list of words displayed in the GUI.
	 * @return The list of words displayed in the GUI
	 */
	public ArrayList<WordListEntry> getCurrentList()
	{
		return currentWordList;
	}
	
	/**
	 * Sets the text of the sentenceField.
	 * @return the sentenceField value
	 */
	public String getSentence() 
	{
		return sentenceField.getText();
	}

	/**
	 * Updates the list with the new matched words.
	 */
	public void updateSentence()
	{
		
		// If there's text:
		if(getSentence().trim().length() <= 0)
			listModel.removeAllElements();
		
		// Clear the current WordList.
		currentWordList.clear();
		// Update using the previously typed word.
		updateList(getSentence().split(" ")[getSentence().split(" ").length-1]);
				
	}
	
	/**
	 * Updates the list with the new matched words and sets the sentenceField String.
	 * @param sentenceFieldString the sentenceField String to set.
	 */
	public void updateSentence(String sentenceFieldString) 
	{
		// Change the sentence the the new sentenceField String.
		sentenceField.setText(sentenceFieldString);
		// Update the list.
		updateSentence();
	}
	
	/**
	 * Adds the specified word to the string.
	 * @param word The word to add to the string.
	 * @return The string with the added word.
	 */
	public String addWord(String word, String line)
	{
		// Check if there's a word.
		if(word.trim().equals(""))
			// If not, return the unmodified line.
			return line;
		
		// Find the last space.
		int spaceIndex = line.trim().lastIndexOf(" ");
		// If there's a space:
		if(spaceIndex > 0)
		{
			// Remove the last word,
			line = line.substring(0, spaceIndex+1);
			// And replace it with the word given.
			line += word;
		}
		// Else if there's no space (no sentence):
		else
		{
			// Use the word as the line.
			line = word;
		}
		
		// Empty the list
		currentWordList.clear();
		
		// Return the updated line with a space at the end.
		return line+" ";
	}
	
	/**
	 * Update the list manually using the given word.
	 * @param word The word to use.
	 */
	private void updateList(String word)
	{	
		// To lower case
		word = word.toLowerCase();
		
		// Empty the list
		listModel.removeAllElements();
		
		// If an empty word is given or if the word ends with an space,
		// then return nothing and use an empty list.
		//
		if(word.equals("") || sentenceField.getText().endsWith(" "))
			return;
		
		// Update the currentWordList with the new word
		currentWordList = wordList.getWords(word);

		// Loop the currentWordList
		Iterator<WordListEntry> iter = currentWordList.iterator();
		while(iter.hasNext())
		{
			// Add the new word to the GUI list
			WordListEntry anEntry = iter.next();
			String aWord = anEntry.getWord();
			listModel.add(listModel.size(), aWord);
		}
	}	
}
